package com.wjm.multithreadingbreakpointcontinuedtransmission;

import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class SingleThreadDownloadActivity extends AppCompatActivity {

    private final Context TAG = SingleThreadDownloadActivity.this;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single_thread_download);
        setTitle( getString(R.string.single_thread_download));
        findViewById();
    }

    private Button btn_single_thread_download_start;
    private ProgressBar pb;
    private TextView tv_pb;
    private String url = "http://gdown.baidu.com/data/wisegame/a7bfb78070894c83/yingyongbao_7232130.apk";

    private void findViewById() {
          btn_single_thread_download_start = findViewById(R.id.btn_single_thread_download_start);
        Button btn_single_thread_download_pause = findViewById(R.id.btn_single_thread_download_pause);
        Button btn_single_thread_download_cancel = findViewById(R.id.btn_single_thread_download_cancel);
        pb = findViewById(R.id.pb);
        tv_pb = findViewById(R.id.tv_pb);
        Button btn_single_thread_download_deletefile = findViewById(R.id.btn_single_thread_download_deletefile);
        btn_single_thread_download_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //单线程下载-开始下载
//                String url = "https://qd.myapp.com/myapp/qqteam/AndroidQQ/mobileqq_android.apk";

//                startDownload(url);

                singleThreadDownload(url);

            }
        });
        btn_single_thread_download_pause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //单线程下载-暂停下载
                if (null != myRunnable) {
                    myRunnable.isPaused = true;
                }
            }
        });
        btn_single_thread_download_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //单线程下载-取消下载
                if (null != myRunnable) {
                    myRunnable.isCanceled = true;
                } else {
                    if (url != null) {
                        // 取消下载时需将文件删除，并将通知关闭
                        String fileName = url.substring(url.lastIndexOf("/"));
                        String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
                        File file = new File(directory + fileName);
                        if (file.exists()) {
                            file.delete();
                        }
                    }
                }

            }
        });
        btn_single_thread_download_deletefile.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (url != null) {
                    // 取消下载时需将文件删除，并将通知关闭
                    String fileName = url.substring(url.lastIndexOf("/"));
                    String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
                    File file = new File(directory + fileName);
                    if (file.exists()) {
                        file.delete();
                    }
                }
            }
        });
    }

    private MyRunnable myRunnable;

    private void singleThreadDownload(String url) {
            myRunnable = new MyRunnable(url);
            Thread t1 = new Thread(myRunnable);
            t1.start();
            btn_single_thread_download_start.setText(getString(R.string.single_thread_download_jx));
    }

    private Handler h = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int what = msg.what;
            switch (what) {
                case TYPE_SUCCESS:
                    Toast.makeText(TAG, "contentLength==downloadedLength 成功", Toast.LENGTH_SHORT).show();
                    Toast.makeText(TAG, "status==TYPE_SUCCESS 下载完成", Toast.LENGTH_SHORT).show();
                    lastProgress = 0;
                    myRunnable = null;
                    btn_single_thread_download_start.setText(getString(R.string.single_thread_download_s));
                    break;
                case TYPE_FAILED:
                    Toast.makeText(TAG, "contentLength==0 失败", Toast.LENGTH_SHORT).show();
                    break;
                case TYPE_PAUSED:
                    Toast.makeText(TAG, "isPaused==true 暂停下载", Toast.LENGTH_SHORT).show();
                    break;
                case TYPE_CANCELED:
                    Toast.makeText(TAG, "isCanceled==true 取消下载", Toast.LENGTH_SHORT).show();
                case TYPE_SET_PROGRESS:
                    int progress = msg.arg1;
                    pb.setProgress(progress);
                    tv_pb.setText(progress + "%");

                default:
                    break;
            }
        }
    };

    private class MyRunnable implements Runnable {

        private String url;
        private boolean isPaused = false;//false为默认不暂停正常下载状态，true为点了暂停
        private boolean isCanceled = false;//false为默认不取消时正常下载状态，true为点了取消

        public MyRunnable(String url) {
            Log.d(MainActivity.TAG, "MyRunnable");
            this.url = url;
        }

        @Override
        public void run() {
            Log.d(MainActivity.TAG, "run start");
            int status = startDownload(this, url);
            Message msg = new Message();
            msg.what = status;
            h.sendMessage(msg);
            Log.d(MainActivity.TAG, "run end");
        }


    }

    public static final int TYPE_SUCCESS = 0;//完成
    public static final int TYPE_FAILED = 1;//失败
    public static final int TYPE_PAUSED = 2;//暂停
    public static final int TYPE_CANCELED = 3;//取消
    public static final int TYPE_SET_PROGRESS = 4;//更新进度

    private int startDownload(MyRunnable myRunnable, String url) {


        InputStream is = null;
        RandomAccessFile savedFile = null;
        File file = null;
        try {
            long downloadedLength = 0; // 记录已下载的文件长度
            String downloadUrl = url;
            String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
            String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
            file = new File(directory + fileName);
            if (file.exists()) {///storage/emulated/0/Download/mobileqq_android.apk
                downloadedLength = file.length();//这里是可以暂停的原因，获取到的是已经下载的文件长度，就从这接着下载
            }
            long contentLength = getContentLength(downloadUrl);//网络文件大小
            if (contentLength == 0) {//53747696
                return TYPE_FAILED;//失败
            } else if (contentLength == downloadedLength) {
                // 已下载字节和文件总字节相等，说明已经下载完成了
                return TYPE_SUCCESS;//成功

            }
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    // 断点下载，指定从哪个字节开始下载
                    .addHeader("RANGE", "bytes=" + downloadedLength + "-")
                    .url(downloadUrl)
                    .build();
            Response response = client.newCall(request).execute();
            if (response != null) {
                is = response.body().byteStream();
                savedFile = new RandomAccessFile(file, "rw");
                savedFile.seek(downloadedLength); // 跳过已下载的字节
                byte[] b = new byte[1024];
                int total = 0;
                int len;
                while ((len = is.read(b)) != -1) {
                    if (myRunnable.isCanceled) {//取消
                        return TYPE_CANCELED;//取消
                    } else if (myRunnable.isPaused) {//暂停
                        return TYPE_PAUSED;

                    } else {
                        total += len;
                        savedFile.write(b, 0, len);
                        // 计算已下载的百分比
                        int progress = (int) ((total + downloadedLength) * 100 / contentLength);
                        publishProgress(progress);//更新进度
                    }
                }
                response.body().close();
                return TYPE_SUCCESS;//成功

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (savedFile != null) {
                    savedFile.close();
                }
                if (myRunnable.isCanceled && file != null) {//取消删除文件
                    file.delete();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    private int lastProgress;

    private void publishProgress(int progress) {
        if (progress > lastProgress) {
            lastProgress = progress;
            Message msg = new Message();
            msg.what = TYPE_SET_PROGRESS;
            msg.arg1 = progress;
            h.sendMessage(msg);
        }

    }

    private long getContentLength(String downloadUrl) throws IOException {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(downloadUrl)
                .build();
        Response response = client.newCall(request).execute();
        if (response != null && response.isSuccessful()) {
            long contentLength = response.body().contentLength();
            response.close();
            return contentLength;
        }
        return 0;
    }

}
